﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Rotempco.Core.Updater.Objects;
using Microsoft.Win32;
using Rotempco.Core.Updater.Logic;
using Rotempco.Core.Logic;

namespace Rotempco.Core.Updater
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private RotempcoSettings GetRotempcoSettings()
        {
            string directory = Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + @"\Rotempco.Core.Updater\";

            if (!Directory.Exists(directory))
                Directory.CreateDirectory(directory);

            return RotempcoSettings.GetProjectSettings(directory + @"Rotempco.Core.Updater.config");
        }

        private string GetMappingsFile()
        {
            FileInfo fileInfo = new FileInfo(textBox_ProjectCoreFile.Text);

            string mappingsFile = fileInfo.FullName.Substring(0, fileInfo.FullName.LastIndexOf('.')) + ".coremapping";
            return mappingsFile;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to Update the Project?" + Environment.NewLine + "All files will be overwritten", "Update core", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                string mappingsFile = GetMappingsFile();
                RotempcoSettings projectSettings = RotempcoSettings.GetProjectSettings(mappingsFile);
                List<DirectorySelection> directoriesSelected = listBox1.Items.Cast<DirectorySelection>().ToList();

                projectSettings.BundleUpdate(() =>
                {
                    projectSettings.SetKey("@DirectorySelection", SerializerLogic.SerializeObject(directoriesSelected));
                });

                string source = new FileInfo(textBox_RotempcoCoreProjectFile.Text).Directory.FullName;
                string destination = new FileInfo(textBox_ProjectCoreFile.Text).Directory.FullName;
                List<string> directoryList = (from d in directoriesSelected where d.Selected == true select d.Name).ToList();

                string basePath = GetBasePath();

                UpdaterLogic.UpdateCore(basePath, projectSettings, source, destination, directoryList, new FileInfo(textBox_ProjectCoreFile.Text).Name.Replace(".csproj", ""));

                LoadSettings(GetMappingsFile()); 

                MessageBox.Show("Done");

            }
        }

        private void button_BrowseToProjectCoreFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "VS project files|*.csproj";
            if (openFileDialog.ShowDialog() == true)
            {
                textBox_ProjectCoreFile.Text = openFileDialog.FileName;

                string mappingsFile = GetMappingsFile();

                if (!File.Exists(mappingsFile))
                {
                    listBox_Safelist.Items.Clear();
                    //listBox_Safelist.Items.Add(@"\Logging\Objects\Stores\LogSettingStore.cs");
                    //listBox_Safelist.Items.Add(@"\ORM\Objects\Stores\EncryptionKeyStore.cs");
                    //listBox_Safelist.Items.Add(@"\ORM\Objects\Stores\DatabaseSettingsStore.cs");
                    //listBox_Safelist.Items.Add(@"\Logging\Logit.cs");
                    //listBox_Safelist.Items.Add(@"\ORM\Logic\DBSelector.cs");

                    SaveSafeList(mappingsFile);
                }

                LoadSettings(mappingsFile); 
            }
        }

        private void SaveSafeList(string mappingsFile)
        {
            RotempcoSettings projectSettings = RotempcoSettings.GetProjectSettings(mappingsFile);
            projectSettings.SetKey("@SafeList", SerializerLogic.SerializeObject(listBox_Safelist.Items.Cast<string>().ToList()));
        }

        private void LoadSettings(string mappingsFile)
        {
            RotempcoSettings globalSettings = GetRotempcoSettings();
            textBox_RotempcoCoreProjectFile.Text = globalSettings.GetValue("@RotempcoCoreProjectFile");
                        
            RotempcoSettings projectSettings = RotempcoSettings.GetProjectSettings(mappingsFile);
            List<DirectorySelection> directorySelection = SerializerLogic.Deserialize(projectSettings.GetValue("@DirectorySelection")) as List<DirectorySelection>;

            List<string> safeList = SerializerLogic.Deserialize(projectSettings.GetValue("@SafeList")) as List<string>;
            listBox_Safelist.Items.Clear();

            if (safeList != null)
                safeList.ForEach(s => listBox_Safelist.Items.Add(s));

            if (directorySelection == null)
                directorySelection = new List<DirectorySelection>();

            LoadDirectorySelection(directorySelection);
        }

        private void LoadDirectorySelection(List<DirectorySelection> directorySelection)
        {
            if (!string.IsNullOrWhiteSpace(textBox_RotempcoCoreProjectFile.Text))
            {
                FileInfo fileInfo = new FileInfo(textBox_RotempcoCoreProjectFile.Text);
                if (Directory.Exists(fileInfo.Directory.FullName))
                {
                    directorySelection.AddRange((from d in fileInfo.Directory.GetDirectories()
                                                 where !d.Name.Equals("bin", StringComparison.CurrentCultureIgnoreCase) &&
                                                 !d.Name.Equals("obj", StringComparison.CurrentCultureIgnoreCase) &&
                                                 !d.Name.Equals(".svn", StringComparison.CurrentCultureIgnoreCase) &&
                                                 !d.Name.Equals("properties", StringComparison.CurrentCultureIgnoreCase) &&
                                                 !DirectorySelectionContains(directorySelection, d.Name)
                                                 select new DirectorySelection() { Name = d.Name, Selected = false, SelectionAvailable = true }));
                }
            }

            (from d in directorySelection where d.Name == "ORM" || d.Name == "Logic" select d).ToList().ForEach(
                d =>
                {
                    d.Selected = true;
                    d.SelectionAvailable = false;
                });

            listBox1.ItemsSource = directorySelection;
        }

        private bool DirectorySelectionContains(List<DirectorySelection> directorySelection, string directoryName)
        {
            return (from d in directorySelection
                    where d.Name.Equals(directoryName, StringComparison.CurrentCultureIgnoreCase)
                    select d).FirstOrDefault() != null;
        }

        private void button_BrowseForRotempcoCoreProjectFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "VS project files|*.csproj";
            if (openFileDialog.ShowDialog() == true)
            {
                textBox_RotempcoCoreProjectFile.Text = openFileDialog.FileName;

                string mappingsFile = GetMappingsFile();
                RotempcoSettings globalSettings = GetRotempcoSettings();
                globalSettings.SetKey("@RotempcoCoreProjectFile", textBox_RotempcoCoreProjectFile.Text);

                LoadDirectorySelection(new List<DirectorySelection>());
            }
        }

        private void button_Add_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Safefiles|*.*";
            openFileDialog.Multiselect = true;

            if (openFileDialog.ShowDialog() == true)
            {
                List<string> safeList = listBox_Safelist.Items.Cast<string>().ToList();
                string basePath = GetBasePath();

                foreach (string fileName in openFileDialog.FileNames)
                {
                    safeList.Add(fileName.Substring(basePath.Count()));
                }

                string mappingsFile = GetMappingsFile();
                RotempcoSettings projectSettings = RotempcoSettings.GetProjectSettings(mappingsFile);
                projectSettings.SetKey("@SafeList", SerializerLogic.SerializeObject(safeList));

                LoadSettings(mappingsFile);
            }
        }

        private string GetBasePath()
        {
            string basePath = textBox_ProjectCoreFile.Text;
            basePath = new FileInfo(basePath).Directory.FullName;
            return basePath;
        }

        private void button_Remove_Click(object sender, RoutedEventArgs e)
        {
            if (listBox_Safelist.SelectedItems.Count > 0)
                listBox_Safelist.SelectedItems.Cast<string>().ToList().ForEach(s =>
                 listBox_Safelist.Items.Remove(s));

            SaveSafeList(GetMappingsFile());
        }
    }
}
